package com.ruoyi.service.purchase.impl;

import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.domain.inventory.MesInventory;
import com.ruoyi.domain.inventory.MesInventoryRecord;
import com.ruoyi.domain.purchase.MesPurchaseReceipt;
import com.ruoyi.domain.purchase.MesPurchaseReceiptItem;
import com.ruoyi.domain.purchase.MesPurchaseReturn;
import com.ruoyi.domain.purchase.MesPurchaseReturnItem;
import com.ruoyi.mapper.purchase.MesPurchaseReceiptItemMapper;
import com.ruoyi.mapper.purchase.MesPurchaseReceiptMapper;
import com.ruoyi.service.inventory.IMesInventoryRecordService;
import com.ruoyi.service.inventory.IMesInventoryService;
import com.ruoyi.service.purchase.IMesPurchaseReceiptService;
import com.ruoyi.service.purchase.IMesPurchaseReturnService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 采购入库主表Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-01-01
 */
@Service
public class MesPurchaseReceiptServiceImpl implements IMesPurchaseReceiptService {
    @Autowired
    private MesPurchaseReceiptMapper mesPurchaseReceiptMapper;

    @Autowired
    private MesPurchaseReceiptItemMapper mesPurchaseReceiptItemMapper;

    @Autowired
    private IMesInventoryService mesInventoryService;

    @Autowired
    private IMesInventoryRecordService mesInventoryRecordService;

    @Autowired
    private IMesPurchaseReturnService mesPurchaseReturnService;

    /**
     * 查询采购入库主表
     * 
     * @param receiptId 采购入库主表主键
     * @return 采购入库主表
     */
    @Override
    public MesPurchaseReceipt selectMesPurchaseReceiptByReceiptId(Long receiptId) {
        MesPurchaseReceipt receipt = mesPurchaseReceiptMapper.selectMesPurchaseReceiptByReceiptId(receiptId);
        if (receipt != null) {
            // 查询明细列表
            List<MesPurchaseReceiptItem> itemList = mesPurchaseReceiptItemMapper.selectItemListByReceiptId(receiptId);
            receipt.setReceiptItemList(itemList);
        }
        return receipt;
    }

    /**
     * 查询采购入库主表列表（排除已入库）
     * 
     * @param mesPurchaseReceipt 采购入库主表
     * @return 采购入库主表
     */
    @Override
    public List<MesPurchaseReceipt> selectMesPurchaseReceiptList(MesPurchaseReceipt mesPurchaseReceipt) {
        // 默认排除已入库的订单
        if (StringUtils.isEmpty(mesPurchaseReceipt.getStatus())) {
            mesPurchaseReceipt.getParams().put("excludeStatus", "RECEIVED");
        }
        return mesPurchaseReceiptMapper.selectMesPurchaseReceiptList(mesPurchaseReceipt);
    }

    /**
     * 新增采购入库主表
     * 
     * @param mesPurchaseReceipt 采购入库主表
     * @return 结果
     */
    @Override
    @Transactional
    public int insertMesPurchaseReceipt(MesPurchaseReceipt mesPurchaseReceipt) {
        // 设置初始状态为待质检
        mesPurchaseReceipt.setStatus("PENDING");
        mesPurchaseReceipt.setCreateTime(DateUtils.getNowDate());
        mesPurchaseReceipt.setCreateBy(SecurityUtils.getUsername());

        int rows = mesPurchaseReceiptMapper.insertMesPurchaseReceipt(mesPurchaseReceipt);

        // 插入明细
        insertReceiptItem(mesPurchaseReceipt);

        return rows;
    }

    /**
     * 修改采购入库主表
     * 
     * @param mesPurchaseReceipt 采购入库主表
     * @return 结果
     */
    @Override
    @Transactional
    public int updateMesPurchaseReceipt(MesPurchaseReceipt mesPurchaseReceipt) {
        mesPurchaseReceipt.setUpdateTime(DateUtils.getNowDate());
        mesPurchaseReceipt.setUpdateBy(SecurityUtils.getUsername());

        // 删除原有明细
        mesPurchaseReceiptItemMapper.deleteMesPurchaseReceiptItemByReceiptId(mesPurchaseReceipt.getReceiptId());

        // 插入新明细
        insertReceiptItem(mesPurchaseReceipt);

        return mesPurchaseReceiptMapper.updateMesPurchaseReceipt(mesPurchaseReceipt);
    }

    /**
     * 批量删除采购入库主表
     * 
     * @param receiptIds 需要删除的采购入库主表主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteMesPurchaseReceiptByReceiptIds(Long[] receiptIds) {
        // 删除明细
        for (Long receiptId : receiptIds) {
            mesPurchaseReceiptItemMapper.deleteMesPurchaseReceiptItemByReceiptId(receiptId);
        }
        return mesPurchaseReceiptMapper.deleteMesPurchaseReceiptByReceiptIds(receiptIds);
    }

    /**
     * 删除采购入库主表信息
     * 
     * @param receiptId 采购入库主表主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteMesPurchaseReceiptByReceiptId(Long receiptId) {
        // 删除明细
        mesPurchaseReceiptItemMapper.deleteMesPurchaseReceiptItemByReceiptId(receiptId);
        return mesPurchaseReceiptMapper.deleteMesPurchaseReceiptByReceiptId(receiptId);
    }

    /**
     * 校验入库单号唯一性
     * 
     * @param receiptCode 入库单号
     * @return 结果
     */
    @Override
    public String checkReceiptCodeUnique(String receiptCode) {
        MesPurchaseReceipt receipt = mesPurchaseReceiptMapper.selectMesPurchaseReceiptByReceiptCode(receiptCode);
        if (StringUtils.isNotNull(receipt)) {
            return "1";
        }
        return "0";
    }

    /**
     * 审核采购入库单
     * 
     * @param receiptId 入库单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int approveMesPurchaseReceipt(Long receiptId) {
        MesPurchaseReceipt receipt = mesPurchaseReceiptMapper.selectMesPurchaseReceiptByReceiptId(receiptId);
        if (receipt == null) {
            throw new RuntimeException("入库单不存在");
        }

        // 更新状态为已审核
        receipt.setStatus("APPROVED");
        receipt.setUpdateTime(DateUtils.getNowDate());
        receipt.setUpdateBy(SecurityUtils.getUsername());

        return mesPurchaseReceiptMapper.updateMesPurchaseReceipt(receipt);
    }

    /**
     * 处理质检结果（重载方法，支持备注）
     * 
     * @param receiptId        入库单ID
     * @param inspectionResult 质检结果（PASS通过 FAIL不通过）
     * @param remark           备注
     * @return 结果
     */
    @Override
    @Transactional
    public int handleInspectionResult(Long receiptId, String inspectionResult, String remark) {
        MesPurchaseReceipt receipt = mesPurchaseReceiptMapper.selectMesPurchaseReceiptByReceiptId(receiptId);
        if (receipt == null) {
            throw new RuntimeException("入库单不存在");
        }

        if ("PASS".equals(inspectionResult)) {
            // 质检通过，更新状态为质检通过
            receipt.setStatus("INSPECTION_PASSED");
            receipt.setInspectionResult("通过");
        } else if ("FAIL".equals(inspectionResult)) {
            // 质检不通过，更新状态为质检不通过，并创建采购退货单
            receipt.setStatus("INSPECTION_FAILED");
            receipt.setInspectionResult("不通过");

            // 创建采购退货单
            createPurchaseReturnFromFailedReceipt(receipt);
        }

        receipt.setRemark(remark);
        receipt.setUpdateTime(DateUtils.getNowDate());
        receipt.setUpdateBy(SecurityUtils.getUsername());

        return mesPurchaseReceiptMapper.updateMesPurchaseReceipt(receipt);
    }

    /**
     * 处理质检结果（两参数版本）
     * 
     * @param receiptId        入库单ID
     * @param inspectionResult 质检结果（PASS通过 FAIL不通过）
     * @return 结果
     */
    @Override
    public int handleInspectionResult(Long receiptId, String inspectionResult) {
        return handleInspectionResult(receiptId, inspectionResult, null);
    }

    /**
     * 根据供应商ID查询入库单列表
     * 
     * @param supplierId 供应商ID
     * @return 入库单列表
     */
    @Override
    public List<MesPurchaseReceipt> selectReceiptListBySupplierId(Long supplierId) {
        return mesPurchaseReceiptMapper.selectReceiptListBySupplierId(supplierId);
    }

    /**
     * 根据仓库ID查询入库单列表
     * 
     * @param warehouseId 仓库ID
     * @return 入库单列表
     */
    @Override
    public List<MesPurchaseReceipt> selectReceiptListByWarehouseId(Long warehouseId) {
        return mesPurchaseReceiptMapper.selectReceiptListByWarehouseId(warehouseId);
    }

    /**
     * 根据状态查询入库单列表
     * 
     * @param status 状态
     * @return 入库单列表
     */
    @Override
    public List<MesPurchaseReceipt> selectReceiptListByStatus(String status) {
        return mesPurchaseReceiptMapper.selectReceiptListByStatus(status);
    }

    /**
     * 执行采购入库
     * 
     * @param receiptId 入库单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int executeMesPurchaseReceipt(Long receiptId) {
        MesPurchaseReceipt receipt = selectMesPurchaseReceiptByReceiptId(receiptId);
        if (receipt == null) {
            throw new RuntimeException("入库单不存在");
        }

        // 只有质检通过的入库单才能执行入库
        if (!"INSPECTION_PASSED".equals(receipt.getStatus())) {
            throw new RuntimeException("只有质检通过的入库单才能执行入库操作");
        }

        List<MesPurchaseReceiptItem> itemList = receipt.getReceiptItemList();
        if (itemList == null || itemList.isEmpty()) {
            throw new RuntimeException("入库明细不能为空");
        }

        // 按物料、批次、仓库分组合并重复物料
        Map<String, List<MesPurchaseReceiptItem>> groupedItems = itemList.stream()
                .collect(Collectors.groupingBy(item -> item.getMaterialId() + "_" +
                        StringUtils.defaultString(item.getBatchCode(), "") + "_" +
                        receipt.getWarehouseId()));

        // 更新库存
        for (Map.Entry<String, List<MesPurchaseReceiptItem>> entry : groupedItems.entrySet()) {
            List<MesPurchaseReceiptItem> items = entry.getValue();
            MesPurchaseReceiptItem firstItem = items.get(0);

            // 计算总数量
            BigDecimal totalQuantity = items.stream()
                    .map(MesPurchaseReceiptItem::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            // 查询现有库存
            MesInventory inventory = new MesInventory();
            inventory.setWarehouseId(receipt.getWarehouseId());
            inventory.setMaterialId(firstItem.getMaterialId());
            inventory.setBatchCode(firstItem.getBatchCode());

            List<MesInventory> existingInventory = mesInventoryService.selectMesInventoryList(inventory);

            if (existingInventory.isEmpty()) {
                // 新增库存记录
                MesInventory newInventory = new MesInventory();
                newInventory.setWarehouseId(receipt.getWarehouseId());
                newInventory.setWarehouseCode(receipt.getWarehouseCode());
                newInventory.setWarehouseName(receipt.getWarehouseName());
                newInventory.setMaterialId(firstItem.getMaterialId());
                newInventory.setMaterialCode(firstItem.getMaterialCode());
                newInventory.setMaterialName(firstItem.getMaterialName());
                newInventory.setSpecification(firstItem.getSpecification());
                newInventory.setUnit(firstItem.getUnit());
                newInventory.setBatchCode(firstItem.getBatchCode());
                newInventory.setQuantity(totalQuantity);
                newInventory.setAvailableQuantity(totalQuantity);
                newInventory.setLocation(firstItem.getLocation());
                newInventory.setCreateTime(DateUtils.getNowDate());
                newInventory.setCreateBy(SecurityUtils.getUsername());

                mesInventoryService.insertMesInventory(newInventory);
            } else {
                // 更新现有库存
                MesInventory existingInv = existingInventory.get(0);
                existingInv.setQuantity(existingInv.getQuantity().add(totalQuantity));
                existingInv.setAvailableQuantity(existingInv.getAvailableQuantity().add(totalQuantity));
                existingInv.setUpdateTime(DateUtils.getNowDate());
                existingInv.setUpdateBy(SecurityUtils.getUsername());

                mesInventoryService.updateMesInventory(existingInv);
            }

            // 记录库存变动
            MesInventoryRecord record = new MesInventoryRecord();
            record.setWarehouseId(receipt.getWarehouseId());
            record.setWarehouseName(receipt.getWarehouseName());
            record.setMaterialId(firstItem.getMaterialId());
            record.setMaterialCode(firstItem.getMaterialCode());
            record.setMaterialName(firstItem.getMaterialName());
            record.setBatchCode(firstItem.getBatchCode());
            record.setQuantity(totalQuantity);
            record.setRelatedOrderId(receipt.getReceiptId());
            record.setRelatedOrderCode(receipt.getReceiptCode());
            record.setOperatorId(SecurityUtils.getUserId());
            record.setOperatorName(SecurityUtils.getUsername());
            record.setRemark("采购入库");
            record.setCreateTime(DateUtils.getNowDate());
            record.setCreateBy(SecurityUtils.getUsername());

            mesInventoryRecordService.insertMesInventoryRecord(record);
        }

        // 更新入库单状态为已入库
        receipt.setStatus("RECEIVED");
        receipt.setOperatorId(SecurityUtils.getUserId());
        receipt.setOperatorName(SecurityUtils.getUsername());
        receipt.setUpdateTime(DateUtils.getNowDate());
        receipt.setUpdateBy(SecurityUtils.getUsername());

        return mesPurchaseReceiptMapper.updateMesPurchaseReceipt(receipt);
    }

    /**
     * 查询已入库的订单列表（用于历史记录）
     * 
     * @param mesPurchaseReceipt 采购入库主表
     * @return 采购入库主表集合
     */
    @Override
    public List<MesPurchaseReceipt> selectReceivedReceiptList(MesPurchaseReceipt mesPurchaseReceipt) {
        mesPurchaseReceipt.setStatus("RECEIVED");
        return mesPurchaseReceiptMapper.selectReceivedReceiptList(mesPurchaseReceipt);
    }

    /**
     * 新增入库明细信息
     * 
     * @param receipt 采购入库对象
     */
    public void insertReceiptItem(MesPurchaseReceipt receipt) {
        List<MesPurchaseReceiptItem> receiptItemList = receipt.getReceiptItemList();
        Long receiptId = receipt.getReceiptId();
        if (StringUtils.isNotNull(receiptItemList)) {
            List<MesPurchaseReceiptItem> list = new ArrayList<MesPurchaseReceiptItem>();
            for (MesPurchaseReceiptItem receiptItem : receiptItemList) {
                receiptItem.setReceiptId(receiptId);
                receiptItem.setCreateTime(DateUtils.getNowDate());
                receiptItem.setCreateBy(SecurityUtils.getUsername());
                list.add(receiptItem);
            }
            if (list.size() > 0) {
                mesPurchaseReceiptItemMapper.batchInsertMesPurchaseReceiptItem(list);
            }
        }
    }

    /**
     * 根据质检不通过的入库单创建采购退货单
     * 
     * @param receipt 入库单
     */
    private void createPurchaseReturnFromFailedReceipt(MesPurchaseReceipt receipt) {
        // 查询入库明细
        List<MesPurchaseReceiptItem> itemList = mesPurchaseReceiptItemMapper
                .selectItemListByReceiptId(receipt.getReceiptId());

        // 创建退货单
        MesPurchaseReturn returnOrder = new MesPurchaseReturn();
        returnOrder.setReturnCode("RT" + DateUtils.dateTimeNow());
        returnOrder.setOriginalReceiptId(receipt.getReceiptId());
        returnOrder.setOriginalReceiptCode(receipt.getReceiptCode());
        returnOrder.setSupplierId(receipt.getSupplierId());
        returnOrder.setSupplierCode(receipt.getSupplierCode());
        returnOrder.setSupplierName(receipt.getSupplierName());
        returnOrder.setWarehouseId(receipt.getWarehouseId());
        returnOrder.setWarehouseCode(receipt.getWarehouseCode());
        returnOrder.setWarehouseName(receipt.getWarehouseName());
        returnOrder.setReturnDate(DateUtils.getNowDate());
        returnOrder.setReturnReason("质检不通过");
        returnOrder.setTotalAmount(receipt.getTotalAmount());
        returnOrder.setTotalQuantity(receipt.getTotalQuantity());
        returnOrder.setReturnType("QUALITY");
        returnOrder.setStatus("PENDING");
        returnOrder.setOperatorId(SecurityUtils.getUserId());
        returnOrder.setOperatorName(SecurityUtils.getUsername());

        // 创建退货明细
        List<MesPurchaseReturnItem> returnItemList = new ArrayList<>();
        for (MesPurchaseReceiptItem receiptItem : itemList) {
            MesPurchaseReturnItem returnItem = new MesPurchaseReturnItem();
            returnItem.setOriginalItemId(receiptItem.getItemId());
            returnItem.setMaterialId(receiptItem.getMaterialId());
            returnItem.setMaterialCode(receiptItem.getMaterialCode());
            returnItem.setMaterialName(receiptItem.getMaterialName());
            returnItem.setSpecification(receiptItem.getSpecification());
            returnItem.setUnit(receiptItem.getUnit());
            returnItem.setBatchCode(receiptItem.getBatchCode());
            returnItem.setQuantity(receiptItem.getQuantity());
            returnItem.setUnitPrice(receiptItem.getUnitPrice());
            returnItem.setTotalPrice(receiptItem.getTotalPrice());
            returnItem.setReturnReason("质检不通过");
            returnItem.setQualityStatus(receiptItem.getQualityStatus());
            returnItem.setLocation(receiptItem.getLocation());
            returnItemList.add(returnItem);
        }
        returnOrder.setReturnItemList(returnItemList);

        // 保存退货单
        mesPurchaseReturnService.insertMesPurchaseReturn(returnOrder);
    }
}